O naufrágio do Titanic é um dos eventos mais conhecidos da história
marítima. Em 15 de abril de 1912, o navio que era considerado
inafundável colidiu com um iceberg e afundou, resultando na morte de
mais de 1.500 pessoas. Esse trágico acontecimento gerou grande comoção
na época e, desde então, tem sido objeto de inúmeras investigações e
estudos.
Análise da Populacional
Vizualização pelo Sexo
# Contar número de passageiros por sexo
passengers_by_sex <- df %>%
group_by(Sex) %>%
summarise(count = n())
# Calcular proporção
passengers_by_sex$prop <- passengers_by_sex$count / sum(passengers_by_sex$count)
# Criar gráfico de barras empilhadas
ggplot(passengers_by_sex, aes(x = Sex, y = prop, fill = Sex)) +
geom_bar(stat = "identity", position = "stack") +
geom_text(aes(label = paste(count, "(", scales::percent(prop), ")")),
position = position_stack(vjust = 0.5), size=4) +
labs(title = "Distribuição de passageiros por sexo", x = "Sexo", y = "Proporção") +
scale_fill_manual(values = c("#998ec3", "#6da8f6")) +
theme(axis.text.x = element_text(angle = 0, vjust = 0.5, hjust=1))

Vizualização pela Sobrevivencia
df %>%
group_by(Survived) %>%
summarise(count = n()) %>%
mutate(prop = count / sum(count),
percent = paste0(round(prop * 100, 1), "%")) %>%
ggplot(aes(x = factor(Survived), y = count, fill = factor(Survived))) +
geom_bar(stat = "identity") +
geom_text(aes(label = percent),
position = position_stack(vjust = 0.5)) +
labs(title = "Quantidade de sobreviventes e mortos",
x = "Sobreviveu?",
y = "Quantidade") +
scale_fill_manual(name = "Sobreviveu?",
values = c("#d3290f", "#52d053"),
labels = c("Não", "Sim"))

Correlações e Direções
# Seleciona apenas as variáveis numéricas e remove linhas com valores faltantes
# Criar o gráfico de correlação
df %>%
select_if(is.numeric) %>% # seleciona apenas as variáveis numéricas
na.omit() %>% # remove as linhas com valores faltantes
cor() %>% # calcula a correlação entre as variáveis
ggcorrplot(lab = TRUE, lab_size = 3, hc.order = TRUE, type = "lower") # cria o gráfico

Análise dos Componentes Principais
# Criar uma variável binária para o gênero e remover as linhas com valores faltantes
df_pca <- df %>%
mutate(Genere = ifelse(Sex == 'female', 1, 0 )) %>% # cria uma variável binária para o gênero
select(Survived, Pclass, Genere, Age, SibSp, Parch, Fare) %>% # seleciona as variáveis numéricas relevantes
drop_na() # remove as linhas com valores faltantes
# Normaliza os dados e executa o PCA
df_pca_norm <- apply(df_pca, 2, scale) # normaliza os dados excluindo a primeira coluna (Survived)
pca <- prcomp(df_pca_norm) # realiza o PCA
# Exibe informações sobre as componentes principais
summary(pca)
Importance of components:
PC1 PC2 PC3 PC4 PC5 PC6 PC7
Standard deviation 1.4573 1.3179 1.0561 0.8467 0.75108 0.65490 0.56059
Proportion of Variance 0.3034 0.2481 0.1593 0.1024 0.08059 0.06127 0.04489
Cumulative Proportion 0.3034 0.5515 0.7108 0.8133 0.89384 0.95511 1.00000
Visualização dos 3PCA | 71% dos Dados
A visualização gráfica das 3 primeiras componentes principais mostrou
que houve uma separação entre os passageiros que sobreviveram e os que
não sobreviveram, sugerindo que essas variáveis foram importantes
# Cria o dataframe com as três primeiras componentes principais e adiciona a variável 'Survived'
df_pca_plot_3d <- as.data.frame(pca$x[, 1:3]) # extrai as três primeiras componentes principais
df_pca_plot_3d$Survived <- factor(df_pca$Survived, levels = c(0, 1), labels = c("Morreu", "Viveu")) #
df_pca_plot_3d$Pclass <- factor(df_pca$Pclass, levels = c(1, 2, 3), labels = c("3", "2", "1"))
df_pca_plot_3d$Genere <- factor(df_pca$Genere, levels = c(0, 1), labels = c("Homem", "Mulher"))
df_pca_plot_3d$SibSp <- factor(df_pca$SibSp, levels = c(0, 1, 2, 3, 4, 5, 6), labels = c("0", "1", "2", "3", "4", "5", "6"))
# Cria o gráfico de dispersão das componentes principais em 3D
plot_ly(df_pca_plot_3d, x = ~PC1, y = ~PC2, z = ~PC3, color = ~factor(Survived), type = "scatter3d", mode = "markers",
colors = c("#EE2E21", "#1D7874"), marker = list(size = 5)) %>%
layout(scene = list(xaxis = list(title = "Componente Principal 1"),
yaxis = list(title = "Componente Principal 2"),
zaxis = list(title = "Componente Principal 3")),
legend = list(title = "Sobreviveu"), title = "Análise de Componentes Principais em 3D")
Componentes pelo Genero
plot_ly(df_pca_plot_3d, x = ~PC1, y = ~PC2, z = ~PC3, color = ~factor(Genere), type = "scatter3d", mode = "markers",
colors = c("#3784B9", "#B9375E"), marker = list(size = 5)) %>%
layout(scene = list(xaxis = list(title = "Componente Principal 1"),
yaxis = list(title = "Componente Principal 2"),
zaxis = list(title = "Componente Principal 3")),
legend = list(title = "Sexo"), title = "Análise de Componentes Principais pelo Gênero")
Componentes pela Classe
plot_ly(df_pca_plot_3d, x = ~PC1, y = ~PC2, z = ~PC3, color = ~factor(Pclass), type = "scatter3d", mode = "markers",
colors = c("#cf2da4", "#2dcf3e", "#2d48cf"), marker = list(size = 5)) %>%
layout(scene = list(xaxis = list(title = "Componente Principal 1"),
yaxis = list(title = "Componente Principal 2"),
zaxis = list(title = "Componente Principal 3")),
legend = list(title = "Sobreviveu"), title = "Análise de Componentes Principais em 3D")
Direção das Variáveis
Utilidade: Entender como as variáveis se relacionam
entre si e com as componentes principais, permitindo a identificação de
padrões e tendências
biplot(pca, scale = 0, cex = 0.6, col = c("white", "#0046FF"))

Sobrevivência por Gênero
Agrupar os dados por gênero e sobrevivência e calcular as
porcentagens de sobrevivência por gênero
Mesmo com o maior número de homens na embarcação. O número de
sobreviventes do sexo feminino foi maior que do sexo masculino.
O número de mulheres sobreviventes foi cerca de 3x maior que o
número de homens sobreviventes.
# agrupar dados e calcular porcentagens
survival_by_gender <- df %>%
group_by(Sex, Survived) %>%
summarise(count = n()) %>%
mutate(percent = count / sum(count) * 100)
`summarise()` has grouped output by 'Sex'. You can override using the `.groups` argument.
# plotar gráfico
ggplot(survival_by_gender, aes(x = Sex, y = percent, fill = factor(Survived))) +
geom_bar(stat = "identity") +
scale_fill_manual(values = c("#d15252", "#52d053"), labels = c("Não Sobreviveu", "Sobreviveu")) +
labs(x = "Gênero", y = "Porcentagem", fill = "") +
theme(plot.title = element_text(size = 16, face = "bold", hjust = 0.5),
axis.title.x = element_text(size = 14),
axis.title.y = element_text(size = 14),
axis.text = element_text(size = 12),
legend.position = "bottom",
legend.title = element_blank(),
legend.text = element_text(size = 12),
panel.grid.major.y = element_line(color = "gray90", size = 0.5),
panel.grid.minor = element_blank()) +
guides(fill = guide_legend(reverse = TRUE, override.aes = list(size=5))) +
geom_text(aes(label = paste0(count, " (", sprintf("%.1f", percent), "%)"), y = percent),
position = position_stack(vjust = 0.5), size = 4, color = "#202124")

Distribuição de Idade dos Passageiros do Titanic
Agrupar os passageiros por faixa etária e analisar o número de
pessoas por faixa no barco
Distribuição de idade em uma escala de 0 a 80 anos. Ajuda a
entender melhor como as idades estão distribuídas entre os passageiros
do navio
A número de passageiros entre 20 e 50 anos é dominante comparado
as demais idades. A média de idade está por volta de 30 anos.
ggplot(df, aes(x = Age)) +
geom_histogram(bins = 20, binwidth = 2, fill = "#5328d4", color = "#202124") +
labs(title = "Distribuição de Idade dos Passageiros", x = "Idade", y = "Frequência") +
theme(plot.title = element_text(size = 14, hjust = 0.5),
axis.title.x = element_text(size = 14),
axis.title.y = element_text(size = 14),
axis.text = element_text(size = 12),
legend.position = "bottom") +
scale_x_continuous(breaks = seq(0, 80, 10)) +
geom_vline(aes(xintercept = mean(Age, na.rm = TRUE)), color = "#86d94e", linetype = "dashed", size = 1) +
annotate("text", x = mean(df$Age, na.rm = TRUE), y = max(df$Age) * 0.9, label = "Média da Idade", color = "#202124", size = 5, fontface = "bold") +
guides(fill = guide_legend(title = "Legenda"))
Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
Please use `linewidth` instead.

Densidade
Agrupar as pessoas por idade e analiasar a densidade da
sobrevivência.
Número relativo de jovens que sobreviveram foi maior que as
demais faixas etárias.
Mesmo assim, o número de jovens mortos chega a cerca de 50% do
valor total de jovens na embarcação.
Número de mortos por volta de 23 anos é muito maior que o número
de sobreviventes.
chance de sobrevivência cai ao passo que a idade do passageiro
aumenta.
# Remover observações com idade faltante
df_age <- df[!is.na(df$Age),]
# Gráfico de densidade para cada grupo de sobreviventes
ggplot(df_age, aes(x = Age, fill = factor(Survived))) +
geom_density(alpha = 0.5) +
labs(title = "Densidade da idade dos passageiros por sobrevivência",
x = "Idade",
y = "Densidade") + theme(legend.position = "bottom") +
scale_fill_manual(name = "Sobreviveu?",
values = c("#d3290f", "#52d053"),
labels = c("Não", "Sim"))

Relacionamento entre Sobrevivência e Idade por Sexo
Identificar se há alguma relação entre a idade dos passageiros do
Titanic e suas chances de sobrevivência, levando em consideração o sexo
dos passageiros -
Novamente, observamos o maior número relativo de mortes dentre
homens e, principalmente, de 20 a 50 anos.
Há um caso que aumenta a chance de sobreviência acima de 80 anos
dentre homens.
df %>%
na.omit() %>%
mutate(age_group = cut(Age, breaks = seq(0, max(Age) + 5, by = 5), right = FALSE, labels = paste0(seq(0, max(Age), by = 5), "-", seq(4, max(Age), by = 5)))) %>%
count(age_group, Survived, Sex) %>%
mutate(Percentage = round(n/sum(n)*100,2)) %>%
ggplot(aes(x = age_group, y = n, fill = factor(Survived))) +
geom_col(position = "dodge") +
geom_text(aes(label = paste0(Percentage, "%")), position = position_dodge(width = 1), vjust = -0.5, color = "#202124", size = 3) +
scale_fill_manual(name = "Sobreviveu?", values = c("#d3290f", "#52d053"), labels = c("Não", "Sim")) +
facet_wrap(~ Sex) +
labs(title = "Frequência de Sobreviventes e Mortes por Idade e Sexo", x = "Idade", y = "Frequência") +
theme(legend.position = "bottom")

Taxa de Sobrevivencia
Relação do número de mortes pelo número total de passageiros por
faixa etária.
Aumento da proporção de mortes por faixa etária. Entretanto, como
já observado, faixa de 19 até 30 anos permanece a com maior densidade de
mortes.
50% dos jovens com 0 a 18 anos não sobreviveu
# Criando um data frame com as variáveis de interesse
df_age_fare <- df %>%
select(Age, Fare, Survived) %>%
na.omit()
# Criando variáveis para categorizar as idades
df_age_fare$age_group <- cut(df_age_fare$Age,
breaks = c(0, 18, 30, 50, Inf),
labels = c("0-18", "19-30", "31-50", "51+"))
# Criando uma nova variável para armazenar as informações sobre sobrevivência
df_age_fare$survival <- ifelse(df_age_fare$Survived == 1, "Survived", "Died")
# Calculando a proporção de sobreviventes e mortos em cada faixa etária
df_age_fare_summary <- df_age_fare %>%
group_by(age_group, survival) %>%
summarise(count = n()) %>%
mutate(prop = count / sum(count))
`summarise()` has grouped output by 'age_group'. You can override using the `.groups` argument.
# Criando um gráfico de barras empilhadas para visualizar a proporção de sobreviventes e mortos em cada faixa etária
ggplot(df_age_fare_summary, aes(x = age_group, y = prop, fill = survival)) +
geom_bar(stat = "identity") +
labs(title = "Proporção de sobreviventes e mortos por faixa etária",
x = "Faixa etária",
y = "Proporção") +
scale_fill_manual(name = "Sobrevivência",
values = c("Died" = "#d3290f", "Survived" = "#52d053"),
labels = c("Mortos", "Sobreviventes"))

Probabilidade de Sobrevivencia pela Classe
Relação do número de mortes pelo número total de passageiros por
classe de passageiros.
Densidade relativa e número bruto de morte altíssimo para a 3°
classe.
Número de passageiros aumenta ao longo das classes, ao passo que
sua chance de sobrevivência diminui.
df %>%
group_by(Pclass, Survived) %>%
summarise(count = n(), .groups = "drop") %>%
mutate(Percentage = round(count/sum(count)*100,2)) %>%
mutate(Survived = ifelse(Survived == 1, "Survived", "Died")) %>%
ggplot(aes(x = factor(Pclass), y = Percentage, fill = Survived)) +
geom_col(position = "dodge") +
geom_text(aes(label = paste0(count)), position = position_dodge(width = 1), vjust = -0.5, color = "#202124", size = 3) +
geom_text(aes(label = paste0(round(Percentage, 0), "%")), position = position_dodge(width = 1), vjust = 1.5, color = "black", size = 3) +
scale_fill_manual(name = "Situação", values = c("#d3290f", "#52d053"), labels = c("Vasco", "Viveu")) +
scale_x_discrete(limits=c("1", "2", "3")) +
labs(title = "Quantidade de sobreviventes e óbitos por classe de passageiros", x = "Classe", y = "Proporção")

Análise nas Mesmas Proporções
Número bruto de sobreviventes e não sobreviventes por classe e
sexo.
Novamente, percebe-se a maior porcentagem de sobrevivência entre
mulheres, principalmente de classes mais altas.
Interessante o fato de que o número de mulheres que sobreviveram
e não sobreviveram na terceira classe é exatamente o mesmo, segundo a
base analisada.
df %>%
mutate(Survived = ifelse(Survived == 1, "Survived", "Died")) %>%
group_by(Pclass, Sex, Survived) %>%
summarise(count = n()) %>%
mutate(Percentage = round(count/sum(count)*100,2)) %>%
ggplot(aes(x = factor(Pclass), y = Percentage, fill = Survived)) +
geom_col(position = "dodge") +
geom_text(aes(label = count), position = position_dodge(width = 1), vjust = -0.5, color = "#202124", size = 3) +
scale_fill_manual(name = "Sobreviveu?", values = c("#d3290f", "#52d053"), labels = c("Não", "Sim")) +
scale_x_discrete(limits = c("1", "2", "3")) +
facet_wrap(~Sex, nrow = 1, scales = "free_x") +
labs(title = "Comparação de sobreviventes e óbitos por classe",
subtitle = "Dados separados por sexo",
x = "Classe",
y = "Porcentagem (%)",
fill = "") +
theme(legend.position = "bottom",
panel.grid.major.x = element_blank(),
panel.grid.minor.x = element_blank())
`summarise()` has grouped output by 'Pclass', 'Sex'. You can override using the `.groups` argument.

Vizualização em Comparação a População
Relação do número de mortes pelo número total de passageiros por
sexo.
Vemos como o número relativo de mortos da terceira classe é muito
maior que comparado a outras classes em ambos os sexos.
Mesmo assim, o número relativo de sobreviventes homens na
terceira classe é maior que da segunda classe.
# Agrupa os dados por classe de passageiros, gênero e sobrevivência
survival_by_class_gender <- df %>%
group_by(Pclass, Survived, Sex) %>%
summarise(count = n())
`summarise()` has grouped output by 'Pclass', 'Survived'. You can override using the `.groups` argument.
# Calcula a proporção e o percentual de sobreviventes em cada categoria
survival_by_class_gender$prop <- survival_by_class_gender$count / sum(survival_by_class_gender$count)
survival_by_class_gender$percent <- paste0(round(survival_by_class_gender$prop * 100, 1), "%")
# Cria um gráfico de barras empilhadas com as proporções de sobrevivência por classe e sobrevivência,
# colorido de acordo com a variável de sobrevivência
ggplot(survival_by_class_gender, aes(x = factor(Pclass), y = prop, fill = factor(Survived))) +
geom_bar(stat = "identity", position = "stack") + # indica que é um gráfico de barras empilhadas
geom_text(aes(label = percent), position = position_stack(vjust = 0.5)) +
labs(title = "Proporção de sobrevivência ao Total", x = "Classe", y = "Proporção") +
theme(legend.position = "bottom") +
scale_fill_manual(name = "Sobreviveu?", values = c("#d3290f", "#52d053"), labels = c("Não", "Sim")) +
facet_wrap(. ~ Sex) # adiciona um facet_wrap para separar os gráficos por gênero

LS0tCnRpdGxlOiAiTyBJbmFmdW5kw6F2ZWwgcXVlIEFmdW5kb3UiCnN1YnRpdGxlOiAiVW1hIGFuw6FsaXNlIGRvcyBwYXNzYWdlaXJvcyBkbyBUaXRhbmljOiBzb2JyZXZpdsOqbmNpYSwgcGVyZmlsIGUgY29ycmVsYcOnw7VlcyIgCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpCmBgYApPIG5hdWZyw6FnaW8gZG8gVGl0YW5pYyDDqSB1bSBkb3MgZXZlbnRvcyBtYWlzIGNvbmhlY2lkb3MgZGEgaGlzdMOzcmlhIG1hcsOtdGltYS4gRW0gMTUgZGUgYWJyaWwgZGUgMTkxMiwgbyBuYXZpbyBxdWUgZXJhIGNvbnNpZGVyYWRvIGluYWZ1bmTDoXZlbCBjb2xpZGl1IGNvbSB1bSBpY2ViZXJnIGUgYWZ1bmRvdSwgcmVzdWx0YW5kbyBuYSBtb3J0ZSBkZSBtYWlzIGRlIDEuNTAwIHBlc3NvYXMuIEVzc2UgdHLDoWdpY28gYWNvbnRlY2ltZW50byBnZXJvdSBncmFuZGUgY29tb8Onw6NvIG5hIMOpcG9jYSBlLCBkZXNkZSBlbnTDo28sIHRlbSBzaWRvIG9iamV0byBkZSBpbsO6bWVyYXMgaW52ZXN0aWdhw6fDtWVzIGUgZXN0dWRvcy4gCgohW10oaHR0cHM6Ly9ici53ZWIuaW1nMi5hY3N0YS5uZXQvcl82NTRfMzY4L25ld3N2Ny8xNy8wNi8wMi8xNC8yNy8wOTEzNzkuanBnKQoKIyMjIEludHJvZHXDp8OjbwpDb20gYmFzZSBub3MgZGFkb3MgZG8gVGl0YW5pYywgYXByZXNlbnRhcmVtb3MgYSBzZWd1aXIgdW1hIGFuw6FsaXNlIHNvYnJlIG9zIHBhc3NhZ2Vpcm9zIGRvIG5hdmlvIHF1ZSBuYXVmcmFnb3UgZW0gMTkxMi4gU2Vyw6NvIGV4cGxvcmFkb3MgZGl2ZXJzb3MgYXNwZWN0b3MsIGNvbW8gYSBkaXN0cmlidWnDp8OjbyBkYXMgY2xhc3NlcyBzb2NpYWlzLCBhIHJlbGHDp8OjbyBlbnRyZSBnw6puZXJvIGUgc29icmV2aXbDqm5jaWEsIGEgaWRhZGUgZG9zIHBhc3NhZ2Vpcm9zLCBlbnRyZSBvdXRyb3MgZmF0b3JlcyByZWxldmFudGVzLgoKIyMjIE9iamV0aXZvCk8gb2JqZXRpdm8gZGEgYW7DoWxpc2Ugw6kgaW52ZXN0aWdhciBlIGNvbXByZWVuZGVyIG8gcGVyZmlsIGRvcyBwYXNzYWdlaXJvcyBlICoqZXhwbG9yYXIgYXMgY2FyYWN0ZXLDrXN0aWNhcyBxdWUgcG9kZW0gdGVyIGluZmx1ZW5jaWFkbyBhcyBjaGFuY2VzIGRlIHNvYnJldml2w6puY2lhIGRvcyBwYXNzYWdlaXJvcyoqLiBBIGZvbnRlIGRvcyBkYWRvcyB1dGlsaXphZG9zIHBvZGUgdmFyaWFyLCBtYXMgYWxndW1hcyBkYXMgbWFpcyBjb211bnMgc8OjbyBvcyByZWdpc3Ryb3Mgb2ZpY2lhaXMgZG9zIHBhc3NhZ2Vpcm9zIGRvIFRpdGFuaWMgZGlzcG9uw612ZWlzIHB1YmxpY2FtZW50ZSwgY29tbyBvcyBmb3JuZWNpZG9zIHBlbG8gc2l0ZSBLYWdnbGUgPGh0dHBzOi8vd3d3LmthZ2dsZS5jb20vYy90aXRhbmljL2RhdGE+IGUgcGVsbyBNdXNldSBNYXLDrXRpbW8gTmFjaW9uYWwgZG9zIEVVQSA8aHR0cHM6Ly93d3cubWFyaXRpbWUub3JnL3RpdGFuaWMvcGFzc2VuZ2Vycy5odG0+LgoKIyMjIEJpYmxpb3RlY2FzCmBgYHtyfQojIENvbGXDp8OjbyBkZSBwYWNvdGVzIHBhcmEgbWFuaXB1bGHDp8OjbyBlIHZpc3VhbGl6YcOnw6NvIGRlIGRhZG9zCmlmKCFyZXF1aXJlKHRpZHl2ZXJzZSkpIGluc3RhbGwucGFja2FnZXMoJ3RpZHl2ZXJzZScpO2xpYnJhcnkodGlkeXZlcnNlKQoKIyBDcmnDp8OjbyBkZSBncsOhZmljb3MgZSB2aXN1YWxpemHDp8O1ZXMgZXN0YXTDrXN0aWNhcwppZighcmVxdWlyZShnZ3Bsb3QyKSkgaW5zdGFsbC5wYWNrYWdlcygnZ2dwbG90MicpO2xpYnJhcnkoZ2dwbG90MikKCiMgTWFuaXB1bGHDp8OjbyBkZSBkYWRvcywgY29tbyBmaWx0cmFnZW0sIHNlbGXDp8OjbyBlIGFncmVnYcOnw6NvCmlmKCFyZXF1aXJlKGRwbHlyKSkgaW5zdGFsbC5wYWNrYWdlcygnZHBseXInKTtsaWJyYXJ5KGRwbHlyKQoKIyBQbG90YXIgbWF0cml6ZXMgZGUgY29ycmVsYcOnw6NvIHVzYW5kbyBnZ3Bsb3QyCmlmKCFyZXF1aXJlKGdnY29ycnBsb3QpKSBpbnN0YWxsLnBhY2thZ2VzKCdnZ2NvcnJwbG90Jyk7bGlicmFyeShnZ2NvcnJwbG90KQppZighcmVxdWlyZShwbG90bHkpKSBpbnN0YWxsLnBhY2thZ2VzKCdwbG90bHknKTtsaWJyYXJ5KHBsb3RseSkKCiMgRnVuw6fDtWVzIHBhcmEgYWp1c3RhciBhIGVzY2FsYSBkb3MgZWl4b3MgZW0gZ3LDoWZpY29zIGdncGxvdDIKaWYoIXJlcXVpcmUoc2NhbGVzKSkgaW5zdGFsbC5wYWNrYWdlcygnc2NhbGVzJyk7bGlicmFyeShzY2FsZXMpCgojIEZvcm5lY2UgZnVuw6fDtWVzIHBhcmEgbWFuaXB1bGHDp8OjbyBkZSBzdHJpbmdzCmlmKCFyZXF1aXJlKHN0cmluZ3IpKSBpbnN0YWxsLnBhY2thZ2VzKCdzdHJpbmdyJyk7bGlicmFyeShzdHJpbmdyKQoKYGBgCgojIyMgSW1wb3J0YcOnw6NvIGRvcyBEYWRvcwoKYGBge3J9CmRmIDwtIHJlYWQuY3N2KCdkYXRhL3RpdGFuaWMuY3N2JykgIyBWYXJpw6F2ZWwgcHJpbmNpcGFsIGBTdXJ2aXZlZApoZWFkKGRmLCAzKQpgYGAKCnwgVmFyacOhdmVsIHwgRGVzY3Jpw6fDo28gfAp8IC0tLSB8IC0tLSB8CnwgUGFzc2VuZ2VySWQgfCBOw7ptZXJvIGRlIGlkZW50aWZpY2HDp8OjbyBkbyBwYXNzYWdlaXJvIHwKfCBTdXJ2aXZlZCB8IFBhc3NhZ2Vpcm8gc29icmV2aXZldSBhbyBuYXVmcsOhZ2lvPyAoMCA9IE7Do287IDEgPSBTaW0pIHwKfCBQY2xhc3MgfCBDbGFzc2Ugb25kZSBvIHBhc3NhZ2Vpcm8gZXN0YXZhIG5vIG5hdmlvICgxID0gMcKqIGNsYXNzZTsgMiA9IDLCqiBjbGFzc2U7IDMgPSAzwqogY2xhc3NlKSB8CnwgTmFtZSB8IE5vbWUgZG8gcGFzc2FnZWlybyB8CnwgU2V4IHwgU2V4byBiaW9sw7NnaWNvIHwKfCBBZ2UgfCBJZGFkZSB8CnwgU2liU3AgfCBOw7ptZXJvIGRlIGlybcOjb3Mgb3UgY8O0bmp1Z2VzIGEgYm9yZG8gfAp8IFBhcmNoIHwgTsO6bWVybyBkZSBwYWlzIG91IGZpbGhvcyBhIGJvcmRvIHwKfCBUaWNrZXQgfCBOw7ptZXJvIGRvIHRpY2tldCBkZSBlbWJhcnF1ZSAocGFzc2FnZW0pIHwKfCBGYXJlIHwgVmFsb3IgZGEgdGFyaWZhIChwcmXDp28gZGEgcGFzc2FnZW0pIGVtIExpYnJhcyBFc3RlcmxpbmFzIHwKfCBDYWJpbiB8IElkZW50aWZpY2HDp8OjbyBkYSBjYWJpbmUgfAp8IEVtYmFya2VkIHwgUG9ydG8gZGUgZW1iYXJxdWUgKEMgPSBDaGVyYm91cmc7IFEgPSBRdWVlbnN0b3duOyBTID0gU291dGhhbXB0b24pIHwKCiMjIEFuw6FsaXNlIGRhIFBvcHVsYWNpb25hbAoKIyMjIyMgVml6dWFsaXphw6fDo28gcGVsbyBTZXhvCgpgYGB7cn0KIyBDb250YXIgbsO6bWVybyBkZSBwYXNzYWdlaXJvcyBwb3Igc2V4bwpwYXNzZW5nZXJzX2J5X3NleCA8LSBkZiAlPiUKICBncm91cF9ieShTZXgpICU+JQogIHN1bW1hcmlzZShjb3VudCA9IG4oKSkKCiMgQ2FsY3VsYXIgcHJvcG9yw6fDo28KcGFzc2VuZ2Vyc19ieV9zZXgkcHJvcCA8LSBwYXNzZW5nZXJzX2J5X3NleCRjb3VudCAvIHN1bShwYXNzZW5nZXJzX2J5X3NleCRjb3VudCkKCiMgQ3JpYXIgZ3LDoWZpY28gZGUgYmFycmFzIGVtcGlsaGFkYXMKZ2dwbG90KHBhc3NlbmdlcnNfYnlfc2V4LCBhZXMoeCA9IFNleCwgeSA9IHByb3AsIGZpbGwgPSBTZXgpKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gInN0YWNrIikgKwogIGdlb21fdGV4dChhZXMobGFiZWwgPSBwYXN0ZShjb3VudCwgIigiLCBzY2FsZXM6OnBlcmNlbnQocHJvcCksICIpIikpLCAKICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9zdGFjayh2anVzdCA9IDAuNSksIHNpemU9NCkgKwogIGxhYnModGl0bGUgPSAiRGlzdHJpYnVpw6fDo28gZGUgcGFzc2FnZWlyb3MgcG9yIHNleG8iLCB4ID0gIlNleG8iLCB5ID0gIlByb3BvcsOnw6NvIikgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIiM5OThlYzMiLCAiIzZkYThmNiIpKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAwLCB2anVzdCA9IDAuNSwgaGp1c3Q9MSkpCgpgYGAKCiMjIyMjIFZpenVhbGl6YcOnw6NvIHBlbGEgU29icmV2aXZlbmNpYQoKYGBge3J9CmRmICU+JQogIGdyb3VwX2J5KFN1cnZpdmVkKSAlPiUKICBzdW1tYXJpc2UoY291bnQgPSBuKCkpICU+JQogIG11dGF0ZShwcm9wID0gY291bnQgLyBzdW0oY291bnQpLCAKICAgICAgICAgcGVyY2VudCA9IHBhc3RlMChyb3VuZChwcm9wICogMTAwLCAxKSwgIiUiKSkgJT4lCiAgZ2dwbG90KGFlcyh4ID0gZmFjdG9yKFN1cnZpdmVkKSwgeSA9IGNvdW50LCBmaWxsID0gZmFjdG9yKFN1cnZpdmVkKSkpICsKICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IikgKwogIGdlb21fdGV4dChhZXMobGFiZWwgPSBwZXJjZW50KSwgCiAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fc3RhY2sodmp1c3QgPSAwLjUpKSArCiAgbGFicyh0aXRsZSA9ICJRdWFudGlkYWRlIGRlIHNvYnJldml2ZW50ZXMgZSBtb3J0b3MiLAogICAgICAgeCA9ICJTb2JyZXZpdmV1PyIsCiAgICAgICB5ID0gIlF1YW50aWRhZGUiKSArCiAgc2NhbGVfZmlsbF9tYW51YWwobmFtZSA9ICJTb2JyZXZpdmV1PyIsCiAgICAgICAgICAgICAgICAgICAgdmFsdWVzID0gYygiI2QzMjkwZiIsICIjNTJkMDUzIiksCiAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiTsOjbyIsICJTaW0iKSkKYGBgCgojIyMgQ29ycmVsYcOnw7VlcyBlIERpcmXDp8O1ZXMKCmBgYHtyfQojIFNlbGVjaW9uYSBhcGVuYXMgYXMgdmFyacOhdmVpcyBudW3DqXJpY2FzIGUgcmVtb3ZlIGxpbmhhcyBjb20gdmFsb3JlcyBmYWx0YW50ZXMKIyBDcmlhciBvIGdyw6FmaWNvIGRlIGNvcnJlbGHDp8OjbwpkZiAlPiUKICBzZWxlY3RfaWYoaXMubnVtZXJpYykgJT4lICAjIHNlbGVjaW9uYSBhcGVuYXMgYXMgdmFyacOhdmVpcyBudW3DqXJpY2FzCiAgbmEub21pdCgpICU+JSAgIyByZW1vdmUgYXMgbGluaGFzIGNvbSB2YWxvcmVzIGZhbHRhbnRlcwogIGNvcigpICU+JSAgIyBjYWxjdWxhIGEgY29ycmVsYcOnw6NvIGVudHJlIGFzIHZhcmnDoXZlaXMKICBnZ2NvcnJwbG90KGxhYiA9IFRSVUUsIGxhYl9zaXplID0gMywgaGMub3JkZXIgPSBUUlVFLCB0eXBlID0gImxvd2VyIikgICMgY3JpYSBvIGdyw6FmaWNvCmBgYAoKIyMjIEFuw6FsaXNlIGRvcyBDb21wb25lbnRlcyBQcmluY2lwYWlzCgpgYGB7cn0KIyBDcmlhciB1bWEgdmFyacOhdmVsIGJpbsOhcmlhIHBhcmEgbyBnw6puZXJvIGUgcmVtb3ZlciBhcyBsaW5oYXMgY29tIHZhbG9yZXMgZmFsdGFudGVzCmRmX3BjYSA8LSBkZiAlPiUgCiAgbXV0YXRlKEdlbmVyZSA9IGlmZWxzZShTZXggPT0gJ2ZlbWFsZScsIDEsIDAgKSkgJT4lICAjIGNyaWEgdW1hIHZhcmnDoXZlbCBiaW7DoXJpYSBwYXJhIG8gZ8OqbmVybwogIHNlbGVjdChTdXJ2aXZlZCwgUGNsYXNzLCBHZW5lcmUsIEFnZSwgU2liU3AsIFBhcmNoLCBGYXJlKSAlPiUgICMgc2VsZWNpb25hIGFzIHZhcmnDoXZlaXMgbnVtw6lyaWNhcyByZWxldmFudGVzCiAgZHJvcF9uYSgpICAjIHJlbW92ZSBhcyBsaW5oYXMgY29tIHZhbG9yZXMgZmFsdGFudGVzCgojIE5vcm1hbGl6YSBvcyBkYWRvcyBlIGV4ZWN1dGEgbyBQQ0EKZGZfcGNhX25vcm0gPC0gYXBwbHkoZGZfcGNhLCAyLCBzY2FsZSkgIyBub3JtYWxpemEgb3MgZGFkb3MgZXhjbHVpbmRvIGEgcHJpbWVpcmEgY29sdW5hIChTdXJ2aXZlZCkKcGNhIDwtIHByY29tcChkZl9wY2Ffbm9ybSkgICMgcmVhbGl6YSBvIFBDQQoKIyBFeGliZSBpbmZvcm1hw6fDtWVzIHNvYnJlIGFzIGNvbXBvbmVudGVzIHByaW5jaXBhaXMKc3VtbWFyeShwY2EpCmBgYAoKIyMgVmlzdWFsaXphw6fDo28gZG9zIDNQQ0EgfCA3MSUgZG9zIERhZG9zCj4gQSB2aXN1YWxpemHDp8OjbyBncsOhZmljYSBkYXMgMyBwcmltZWlyYXMgY29tcG9uZW50ZXMgcHJpbmNpcGFpcyBtb3N0cm91IHF1ZSBob3V2ZSB1bWEgc2VwYXJhw6fDo28gZW50cmUgb3MgcGFzc2FnZWlyb3MgcXVlIHNvYnJldml2ZXJhbSBlIG9zIHF1ZSBuw6NvIHNvYnJldml2ZXJhbSwgc3VnZXJpbmRvIHF1ZSBlc3NhcyB2YXJpw6F2ZWlzIGZvcmFtIGltcG9ydGFudGVzCgpgYGB7cn0KIyBDcmlhIG8gZGF0YWZyYW1lIGNvbSBhcyB0csOqcyBwcmltZWlyYXMgY29tcG9uZW50ZXMgcHJpbmNpcGFpcyBlIGFkaWNpb25hIGEgdmFyacOhdmVsICdTdXJ2aXZlZCcKZGZfcGNhX3Bsb3RfM2QgPC0gYXMuZGF0YS5mcmFtZShwY2EkeFssIDE6M10pICAjIGV4dHJhaSBhcyB0csOqcyBwcmltZWlyYXMgY29tcG9uZW50ZXMgcHJpbmNpcGFpcwpkZl9wY2FfcGxvdF8zZCRTdXJ2aXZlZCA8LSBmYWN0b3IoZGZfcGNhJFN1cnZpdmVkLCBsZXZlbHMgPSBjKDAsIDEpLCBsYWJlbHMgPSBjKCJNb3JyZXUiLCAiVml2ZXUiKSkgICMKZGZfcGNhX3Bsb3RfM2QkUGNsYXNzIDwtIGZhY3RvcihkZl9wY2EkUGNsYXNzLCBsZXZlbHMgPSBjKDEsIDIsIDMpLCBsYWJlbHMgPSBjKCIzIiwgIjIiLCAiMSIpKQpkZl9wY2FfcGxvdF8zZCRHZW5lcmUgPC0gZmFjdG9yKGRmX3BjYSRHZW5lcmUsIGxldmVscyA9IGMoMCwgMSksIGxhYmVscyA9IGMoIkhvbWVtIiwgIk11bGhlciIpKQpkZl9wY2FfcGxvdF8zZCRTaWJTcCA8LSBmYWN0b3IoZGZfcGNhJFNpYlNwLCBsZXZlbHMgPSBjKDAsIDEsIDIsIDMsIDQsIDUsIDYpLCBsYWJlbHMgPSBjKCIwIiwgIjEiLCAiMiIsICIzIiwgIjQiLCAiNSIsICI2IikpCgojIENyaWEgbyBncsOhZmljbyBkZSBkaXNwZXJzw6NvIGRhcyBjb21wb25lbnRlcyBwcmluY2lwYWlzIGVtIDNECnBsb3RfbHkoZGZfcGNhX3Bsb3RfM2QsIHggPSB+UEMxLCB5ID0gflBDMiwgeiA9IH5QQzMsIGNvbG9yID0gfmZhY3RvcihTdXJ2aXZlZCksIHR5cGUgPSAic2NhdHRlcjNkIiwgbW9kZSA9ICJtYXJrZXJzIiwKICAgICAgICBjb2xvcnMgPSBjKCIjRUUyRTIxIiwgIiMxRDc4NzQiKSwgbWFya2VyID0gbGlzdChzaXplID0gNSkpICU+JQogIGxheW91dChzY2VuZSA9IGxpc3QoeGF4aXMgPSBsaXN0KHRpdGxlID0gIkNvbXBvbmVudGUgUHJpbmNpcGFsIDEiKSwKICAgICAgICAgICAgICAgICAgICAgIHlheGlzID0gbGlzdCh0aXRsZSA9ICJDb21wb25lbnRlIFByaW5jaXBhbCAyIiksCiAgICAgICAgICAgICAgICAgICAgICB6YXhpcyA9IGxpc3QodGl0bGUgPSAiQ29tcG9uZW50ZSBQcmluY2lwYWwgMyIpKSwKICAgICAgICAgbGVnZW5kID0gbGlzdCh0aXRsZSA9ICJTb2JyZXZpdmV1IiksIHRpdGxlID0gIkFuw6FsaXNlIGRlIENvbXBvbmVudGVzIFByaW5jaXBhaXMgZW0gM0QiKQpgYGAKCiMjIyBDb21wb25lbnRlcyBwZWxvIEdlbmVybwoKYGBge3J9CnBsb3RfbHkoZGZfcGNhX3Bsb3RfM2QsIHggPSB+UEMxLCB5ID0gflBDMiwgeiA9IH5QQzMsIGNvbG9yID0gfmZhY3RvcihHZW5lcmUpLCB0eXBlID0gInNjYXR0ZXIzZCIsIG1vZGUgPSAibWFya2VycyIsCiAgICAgICAgY29sb3JzID0gYygiIzM3ODRCOSIsICIjQjkzNzVFIiksIG1hcmtlciA9IGxpc3Qoc2l6ZSA9IDUpKSAlPiUKICBsYXlvdXQoc2NlbmUgPSBsaXN0KHhheGlzID0gbGlzdCh0aXRsZSA9ICJDb21wb25lbnRlIFByaW5jaXBhbCAxIiksCiAgICAgICAgICAgICAgICAgICAgICB5YXhpcyA9IGxpc3QodGl0bGUgPSAiQ29tcG9uZW50ZSBQcmluY2lwYWwgMiIpLAogICAgICAgICAgICAgICAgICAgICAgemF4aXMgPSBsaXN0KHRpdGxlID0gIkNvbXBvbmVudGUgUHJpbmNpcGFsIDMiKSksCiAgICAgICAgIGxlZ2VuZCA9IGxpc3QodGl0bGUgPSAiU2V4byIpLCB0aXRsZSA9ICJBbsOhbGlzZSBkZSBDb21wb25lbnRlcyBQcmluY2lwYWlzIHBlbG8gR8OqbmVybyIpCmBgYAojIyMgQ29tcG9uZW50ZXMgcGVsYSBDbGFzc2UKCmBgYHtyfQpwbG90X2x5KGRmX3BjYV9wbG90XzNkLCB4ID0gflBDMSwgeSA9IH5QQzIsIHogPSB+UEMzLCBjb2xvciA9IH5mYWN0b3IoUGNsYXNzKSwgdHlwZSA9ICJzY2F0dGVyM2QiLCBtb2RlID0gIm1hcmtlcnMiLAogICAgICAgIGNvbG9ycyA9IGMoIiNjZjJkYTQiLCAiIzJkY2YzZSIsICIjMmQ0OGNmIiksIG1hcmtlciA9IGxpc3Qoc2l6ZSA9IDUpKSAlPiUKICBsYXlvdXQoc2NlbmUgPSBsaXN0KHhheGlzID0gbGlzdCh0aXRsZSA9ICJDb21wb25lbnRlIFByaW5jaXBhbCAxIiksCiAgICAgICAgICAgICAgICAgICAgICB5YXhpcyA9IGxpc3QodGl0bGUgPSAiQ29tcG9uZW50ZSBQcmluY2lwYWwgMiIpLAogICAgICAgICAgICAgICAgICAgICAgemF4aXMgPSBsaXN0KHRpdGxlID0gIkNvbXBvbmVudGUgUHJpbmNpcGFsIDMiKSksCiAgICAgICAgIGxlZ2VuZCA9IGxpc3QodGl0bGUgPSAiU29icmV2aXZldSIpLCB0aXRsZSA9ICJBbsOhbGlzZSBkZSBDb21wb25lbnRlcyBQcmluY2lwYWlzIGVtIDNEIikKYGBgCgoKIyMjIERpcmXDp8OjbyBkYXMgVmFyacOhdmVpcwo+ICoqVXRpbGlkYWRlOioqIEVudGVuZGVyIGNvbW8gYXMgdmFyacOhdmVpcyBzZSByZWxhY2lvbmFtIGVudHJlIHNpIGUgY29tIGFzIGNvbXBvbmVudGVzIHByaW5jaXBhaXMsIHBlcm1pdGluZG8gYSBpZGVudGlmaWNhw6fDo28gZGUgcGFkcsO1ZXMgZSB0ZW5kw6puY2lhcwoKYGBge3IsIGZpZy5oZWlnaHQ9NywgZmlnLndpZHRoPTd9CmJpcGxvdChwY2EsIHNjYWxlID0gMCwgY2V4ID0gMC42LCBjb2wgPSBjKCJ3aGl0ZSIsICIjMDA0NkZGIikpCmBgYAoKIyMjIFNvYnJldml2w6puY2lhIHBvciBHw6puZXJvCj4gQWdydXBhciBvcyBkYWRvcyBwb3IgZ8OqbmVybyBlIHNvYnJldml2w6puY2lhIGUgY2FsY3VsYXIgYXMgcG9yY2VudGFnZW5zIGRlIHNvYnJldml2w6puY2lhIHBvciBnw6puZXJvCgotIE1lc21vIGNvbSBvIG1haW9yIG7Dum1lcm8gZGUgaG9tZW5zIG5hIGVtYmFyY2HDp8Ojby4gTyBuw7ptZXJvIGRlIHNvYnJldml2ZW50ZXMgZG8gc2V4byBmZW1pbmlubyBmb2kgbWFpb3IgcXVlIGRvIHNleG8gbWFzY3VsaW5vLgoKLSBPIG7Dum1lcm8gZGUgbXVsaGVyZXMgc29icmV2aXZlbnRlcyBmb2kgY2VyY2EgZGUgM3ggbWFpb3IgcXVlIG8gbsO6bWVybyBkZSBob21lbnMgc29icmV2aXZlbnRlcy4KCgpgYGB7cn0KIyBhZ3J1cGFyIGRhZG9zIGUgY2FsY3VsYXIgcG9yY2VudGFnZW5zCnN1cnZpdmFsX2J5X2dlbmRlciA8LSBkZiAlPiUKICBncm91cF9ieShTZXgsIFN1cnZpdmVkKSAlPiUKICBzdW1tYXJpc2UoY291bnQgPSBuKCkpICU+JQogIG11dGF0ZShwZXJjZW50ID0gY291bnQgLyBzdW0oY291bnQpICogMTAwKQoKIyBwbG90YXIgZ3LDoWZpY28KZ2dwbG90KHN1cnZpdmFsX2J5X2dlbmRlciwgYWVzKHggPSBTZXgsIHkgPSBwZXJjZW50LCBmaWxsID0gZmFjdG9yKFN1cnZpdmVkKSkpICsKICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IikgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIiNkMTUyNTIiLCAiIzUyZDA1MyIpLCBsYWJlbHMgPSBjKCJOw6NvIFNvYnJldml2ZXUiLCAiU29icmV2aXZldSIpKSArCiAgbGFicyh4ID0gIkfDqm5lcm8iLCB5ID0gIlBvcmNlbnRhZ2VtIiwgZmlsbCA9ICIiKSArCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTYsIGZhY2UgPSAiYm9sZCIsIGhqdXN0ID0gMC41KSwKICAgICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0KSwKICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0KSwKICAgICAgICBheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwKICAgICAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgICAgICBwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2xpbmUoY29sb3IgPSAiZ3JheTkwIiwgc2l6ZSA9IDAuNSksCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSkgKwogIGd1aWRlcyhmaWxsID0gZ3VpZGVfbGVnZW5kKHJldmVyc2UgPSBUUlVFLCBvdmVycmlkZS5hZXMgPSBsaXN0KHNpemU9NSkpKSArCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHBhc3RlMChjb3VudCwgIiAoIiwgc3ByaW50ZigiJS4xZiIsIHBlcmNlbnQpLCAiJSkiKSwgeSA9IHBlcmNlbnQpLCAKICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9zdGFjayh2anVzdCA9IDAuNSksIHNpemUgPSA0LCBjb2xvciA9ICIjMjAyMTI0IikKCmBgYAoKIyMjIERpc3RyaWJ1acOnw6NvIGRlIElkYWRlIGRvcyBQYXNzYWdlaXJvcyBkbyBUaXRhbmljCj4gQWdydXBhciBvcyBwYXNzYWdlaXJvcyBwb3IgZmFpeGEgZXTDoXJpYSBlIGFuYWxpc2FyIG8gbsO6bWVybyBkZSBwZXNzb2FzIHBvciBmYWl4YSBubyBiYXJjbwoKLSAgRGlzdHJpYnVpw6fDo28gZGUgaWRhZGUgZW0gdW1hIGVzY2FsYSBkZSAwIGEgODAgYW5vcy4gQWp1ZGEgYSBlbnRlbmRlciBtZWxob3IgY29tbyBhcyBpZGFkZXMgZXN0w6NvIGRpc3RyaWJ1w61kYXMgZW50cmUgb3MgcGFzc2FnZWlyb3MgZG8gbmF2aW8KCi0gIEEgbsO6bWVybyBkZSBwYXNzYWdlaXJvcyBlbnRyZSAyMCBlIDUwIGFub3Mgw6kgZG9taW5hbnRlIGNvbXBhcmFkbyBhcyBkZW1haXMgaWRhZGVzLiBBIG3DqWRpYSBkZSBpZGFkZSBlc3TDoSBwb3Igdm9sdGEgZGUgMzAgYW5vcy4KCmBgYHtyfQpnZ3Bsb3QoZGYsIGFlcyh4ID0gQWdlKSkgKwogIGdlb21faGlzdG9ncmFtKGJpbnMgPSAyMCwgYmlud2lkdGggPSAyLCBmaWxsID0gIiM1MzI4ZDQiLCBjb2xvciA9ICIjMjAyMTI0IikgKwogIGxhYnModGl0bGUgPSAiRGlzdHJpYnVpw6fDo28gZGUgSWRhZGUgZG9zIFBhc3NhZ2Vpcm9zIiwgeCA9ICJJZGFkZSIsIHkgPSAiRnJlcXXDqm5jaWEiKSArCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQsIGhqdXN0ID0gMC41KSwKICAgICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0KSwKICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0KSwKICAgICAgICBheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoMCwgODAsIDEwKSkgKwogIGdlb21fdmxpbmUoYWVzKHhpbnRlcmNlcHQgPSBtZWFuKEFnZSwgbmEucm0gPSBUUlVFKSksIGNvbG9yID0gIiM4NmQ5NGUiLCBsaW5ldHlwZSA9ICJkYXNoZWQiLCBzaXplID0gMSkgKwogIGFubm90YXRlKCJ0ZXh0IiwgeCA9IG1lYW4oZGYkQWdlLCBuYS5ybSA9IFRSVUUpLCB5ID0gbWF4KGRmJEFnZSkgKiAwLjksIGxhYmVsID0gIk3DqWRpYSBkYSBJZGFkZSIsIGNvbG9yID0gIiMyMDIxMjQiLCBzaXplID0gNSwgZm9udGZhY2UgPSAiYm9sZCIpICsKICBndWlkZXMoZmlsbCA9IGd1aWRlX2xlZ2VuZCh0aXRsZSA9ICJMZWdlbmRhIikpCgpgYGAKCiMjIyMjIERlbnNpZGFkZQo+ICBBZ3J1cGFyIGFzIHBlc3NvYXMgcG9yIGlkYWRlIGUgYW5hbGlhc2FyIGEgZGVuc2lkYWRlIGRhIHNvYnJldml2w6puY2lhLgoKLSAgTsO6bWVybyByZWxhdGl2byBkZSBqb3ZlbnMgcXVlIHNvYnJldml2ZXJhbSBmb2kgbWFpb3IgcXVlIGFzIGRlbWFpcyBmYWl4YXMgZXTDoXJpYXMuCgotICBNZXNtbyBhc3NpbSwgbyBuw7ptZXJvIGRlIGpvdmVucyBtb3J0b3MgY2hlZ2EgYSBjZXJjYSBkZSA1MCUgZG8gdmFsb3IgdG90YWwgZGUgam92ZW5zIG5hIGVtYmFyY2HDp8Ojby4KCi0gIE7Dum1lcm8gZGUgbW9ydG9zIHBvciB2b2x0YSBkZSAyMyBhbm9zIMOpIG11aXRvIG1haW9yIHF1ZSBvIG7Dum1lcm8gZGUgc29icmV2aXZlbnRlcy4KCi0gIGNoYW5jZSBkZSBzb2JyZXZpdsOqbmNpYSBjYWkgYW8gcGFzc28gcXVlIGEgaWRhZGUgZG8gcGFzc2FnZWlybyBhdW1lbnRhLgoKYGBge3J9CiMgUmVtb3ZlciBvYnNlcnZhw6fDtWVzIGNvbSBpZGFkZSBmYWx0YW50ZQpkZl9hZ2UgPC0gZGZbIWlzLm5hKGRmJEFnZSksXQoKIyBHcsOhZmljbyBkZSBkZW5zaWRhZGUgcGFyYSBjYWRhIGdydXBvIGRlIHNvYnJldml2ZW50ZXMKZ2dwbG90KGRmX2FnZSwgYWVzKHggPSBBZ2UsIGZpbGwgPSBmYWN0b3IoU3Vydml2ZWQpKSkgKwogIGdlb21fZGVuc2l0eShhbHBoYSA9IDAuNSkgKwogIGxhYnModGl0bGUgPSAiRGVuc2lkYWRlIGRhIGlkYWRlIGRvcyBwYXNzYWdlaXJvcyBwb3Igc29icmV2aXbDqm5jaWEiLAogICAgICAgeCA9ICJJZGFkZSIsCiAgICAgICB5ID0gIkRlbnNpZGFkZSIpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpICsKICBzY2FsZV9maWxsX21hbnVhbChuYW1lID0gIlNvYnJldml2ZXU/IiwKICAgICAgICAgICAgICAgICAgICB2YWx1ZXMgPSBjKCIjZDMyOTBmIiwgIiM1MmQwNTMiKSwKICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCJOw6NvIiwgIlNpbSIpKQpgYGAKCgojIyMgUmVsYWNpb25hbWVudG8gZW50cmUgU29icmV2aXbDqm5jaWEgZSBJZGFkZSBwb3IgU2V4bwo+IElkZW50aWZpY2FyIHNlIGjDoSBhbGd1bWEgcmVsYcOnw6NvIGVudHJlIGEgaWRhZGUgZG9zIHBhc3NhZ2Vpcm9zIGRvIFRpdGFuaWMgZSBzdWFzIGNoYW5jZXMgZGUgc29icmV2aXbDqm5jaWEsIGxldmFuZG8gZW0gY29uc2lkZXJhw6fDo28gbyBzZXhvIGRvcyBwYXNzYWdlaXJvcyAtCgotICBOb3ZhbWVudGUsIG9ic2VydmFtb3MgbyBtYWlvciBuw7ptZXJvIHJlbGF0aXZvIGRlIG1vcnRlcyBkZW50cmUgaG9tZW5zIGUsIHByaW5jaXBhbG1lbnRlLCBkZSAyMCBhIDUwIGFub3MuIAoKLSAgSMOhIHVtIGNhc28gcXVlIGF1bWVudGEgYSBjaGFuY2UgZGUgc29icmV2acOqbmNpYSBhY2ltYSBkZSA4MCBhbm9zIGRlbnRyZSBob21lbnMuCgpgYGB7ciwgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9MTMuNX0KZGYgJT4lCiAgbmEub21pdCgpICU+JQogIG11dGF0ZShhZ2VfZ3JvdXAgPSBjdXQoQWdlLCBicmVha3MgPSBzZXEoMCwgbWF4KEFnZSkgKyA1LCBieSA9IDUpLCByaWdodCA9IEZBTFNFLCBsYWJlbHMgPSBwYXN0ZTAoc2VxKDAsIG1heChBZ2UpLCBieSA9IDUpLCAiLSIsIHNlcSg0LCBtYXgoQWdlKSwgYnkgPSA1KSkpKSAlPiUKICBjb3VudChhZ2VfZ3JvdXAsIFN1cnZpdmVkLCBTZXgpICU+JQogIG11dGF0ZShQZXJjZW50YWdlID0gcm91bmQobi9zdW0obikqMTAwLDIpKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBhZ2VfZ3JvdXAsIHkgPSBuLCBmaWxsID0gZmFjdG9yKFN1cnZpdmVkKSkpICsKICBnZW9tX2NvbChwb3NpdGlvbiA9ICJkb2RnZSIpICsKICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcGFzdGUwKFBlcmNlbnRhZ2UsICIlIikpLCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMSksIHZqdXN0ID0gLTAuNSwgY29sb3IgPSAiIzIwMjEyNCIsIHNpemUgPSAzKSArCiAgc2NhbGVfZmlsbF9tYW51YWwobmFtZSA9ICJTb2JyZXZpdmV1PyIsIHZhbHVlcyA9IGMoIiNkMzI5MGYiLCAiIzUyZDA1MyIpLCBsYWJlbHMgPSBjKCJOw6NvIiwgIlNpbSIpKSArCiAgZmFjZXRfd3JhcCh+IFNleCkgKwogIGxhYnModGl0bGUgPSAiRnJlcXXDqm5jaWEgZGUgU29icmV2aXZlbnRlcyBlIE1vcnRlcyBwb3IgSWRhZGUgZSBTZXhvIiwgeCA9ICJJZGFkZSIsIHkgPSAiRnJlcXXDqm5jaWEiKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpCmBgYAoKIyMjIFRheGEgZGUgU29icmV2aXZlbmNpYQo+IFJlbGHDp8OjbyBkbyBuw7ptZXJvIGRlIG1vcnRlcyBwZWxvIG7Dum1lcm8gdG90YWwgZGUgcGFzc2FnZWlyb3MgcG9yIGZhaXhhIGV0w6FyaWEuCgotICBBdW1lbnRvIGRhIHByb3BvcsOnw6NvIGRlIG1vcnRlcyBwb3IgZmFpeGEgZXTDoXJpYS4gRW50cmV0YW50bywgY29tbyBqw6Egb2JzZXJ2YWRvLCBmYWl4YSBkZSAxOSBhdMOpIDMwIGFub3MgcGVybWFuZWNlIGEgY29tIG1haW9yIGRlbnNpZGFkZSBkZSBtb3J0ZXMuICAKCi0gNTAlIGRvcyBqb3ZlbnMgY29tIDAgYSAxOCBhbm9zIG7Do28gc29icmV2aXZldQoKYGBge3J9CiMgQ3JpYW5kbyB1bSBkYXRhIGZyYW1lIGNvbSBhcyB2YXJpw6F2ZWlzIGRlIGludGVyZXNzZQpkZl9hZ2VfZmFyZSA8LSBkZiAlPiUKICBzZWxlY3QoQWdlLCBGYXJlLCBTdXJ2aXZlZCkgJT4lCiAgbmEub21pdCgpCgojIENyaWFuZG8gdmFyacOhdmVpcyBwYXJhIGNhdGVnb3JpemFyIGFzIGlkYWRlcwpkZl9hZ2VfZmFyZSRhZ2VfZ3JvdXAgPC0gY3V0KGRmX2FnZV9mYXJlJEFnZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWtzID0gYygwLCAxOCwgMzAsIDUwLCBJbmYpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCIwLTE4IiwgIjE5LTMwIiwgIjMxLTUwIiwgIjUxKyIpKQoKIyBDcmlhbmRvIHVtYSBub3ZhIHZhcmnDoXZlbCBwYXJhIGFybWF6ZW5hciBhcyBpbmZvcm1hw6fDtWVzIHNvYnJlIHNvYnJldml2w6puY2lhCmRmX2FnZV9mYXJlJHN1cnZpdmFsIDwtIGlmZWxzZShkZl9hZ2VfZmFyZSRTdXJ2aXZlZCA9PSAxLCAiU3Vydml2ZWQiLCAiRGllZCIpCgojIENhbGN1bGFuZG8gYSBwcm9wb3LDp8OjbyBkZSBzb2JyZXZpdmVudGVzIGUgbW9ydG9zIGVtIGNhZGEgZmFpeGEgZXTDoXJpYQpkZl9hZ2VfZmFyZV9zdW1tYXJ5IDwtIGRmX2FnZV9mYXJlICU+JQogIGdyb3VwX2J5KGFnZV9ncm91cCwgc3Vydml2YWwpICU+JQogIHN1bW1hcmlzZShjb3VudCA9IG4oKSkgJT4lCiAgbXV0YXRlKHByb3AgPSBjb3VudCAvIHN1bShjb3VudCkpCgojIENyaWFuZG8gdW0gZ3LDoWZpY28gZGUgYmFycmFzIGVtcGlsaGFkYXMgcGFyYSB2aXN1YWxpemFyIGEgcHJvcG9yw6fDo28gZGUgc29icmV2aXZlbnRlcyBlIG1vcnRvcyBlbSBjYWRhIGZhaXhhIGV0w6FyaWEKZ2dwbG90KGRmX2FnZV9mYXJlX3N1bW1hcnksIGFlcyh4ID0gYWdlX2dyb3VwLCB5ID0gcHJvcCwgZmlsbCA9IHN1cnZpdmFsKSkgKwogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiKSArCiAgbGFicyh0aXRsZSA9ICJQcm9wb3LDp8OjbyBkZSBzb2JyZXZpdmVudGVzIGUgbW9ydG9zIHBvciBmYWl4YSBldMOhcmlhIiwKICAgICAgIHggPSAiRmFpeGEgZXTDoXJpYSIsCiAgICAgICB5ID0gIlByb3BvcsOnw6NvIikgKwogIHNjYWxlX2ZpbGxfbWFudWFsKG5hbWUgPSAiU29icmV2aXbDqm5jaWEiLCAKICAgICAgICAgICAgICAgICAgICB2YWx1ZXMgPSBjKCJEaWVkIiA9ICIjZDMyOTBmIiwgIlN1cnZpdmVkIiA9ICIjNTJkMDUzIiksCiAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiTW9ydG9zIiwgIlNvYnJldml2ZW50ZXMiKSkKYGBgCgoKIyMgUHJvYmFiaWxpZGFkZSBkZSBTb2JyZXZpdmVuY2lhIHBlbGEgQ2xhc3NlCj4gUmVsYcOnw6NvIGRvIG7Dum1lcm8gZGUgbW9ydGVzIHBlbG8gbsO6bWVybyB0b3RhbCBkZSBwYXNzYWdlaXJvcyBwb3IgY2xhc3NlIGRlIHBhc3NhZ2Vpcm9zLgoKLSAgRGVuc2lkYWRlIHJlbGF0aXZhIGUgbsO6bWVybyBicnV0byBkZSBtb3J0ZSBhbHTDrXNzaW1vIHBhcmEgYSAzwrAgY2xhc3NlLiAKCi0gTsO6bWVybyBkZSBwYXNzYWdlaXJvcyBhdW1lbnRhIGFvIGxvbmdvIGRhcyBjbGFzc2VzLCBhbyBwYXNzbyBxdWUgc3VhIGNoYW5jZSBkZSBzb2JyZXZpdsOqbmNpYSBkaW1pbnVpLgoKCmBgYHtyLCBmaWcud2lkdGg9OSwgZmlnLmhlaWdodD01fQpkZiAlPiUKICBncm91cF9ieShQY2xhc3MsIFN1cnZpdmVkKSAlPiUKICBzdW1tYXJpc2UoY291bnQgPSBuKCksIC5ncm91cHMgPSAiZHJvcCIpICU+JQogIG11dGF0ZShQZXJjZW50YWdlID0gcm91bmQoY291bnQvc3VtKGNvdW50KSoxMDAsMikpICU+JQogIG11dGF0ZShTdXJ2aXZlZCA9IGlmZWxzZShTdXJ2aXZlZCA9PSAxLCAiU3Vydml2ZWQiLCAiRGllZCIpKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBmYWN0b3IoUGNsYXNzKSwgeSA9IFBlcmNlbnRhZ2UsIGZpbGwgPSBTdXJ2aXZlZCkpICsKICBnZW9tX2NvbChwb3NpdGlvbiA9ICJkb2RnZSIpICsKICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcGFzdGUwKGNvdW50KSksIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAxKSwgdmp1c3QgPSAtMC41LCBjb2xvciA9ICIjMjAyMTI0Iiwgc2l6ZSA9IDMpICsKICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcGFzdGUwKHJvdW5kKFBlcmNlbnRhZ2UsIDApLCAiJSIpKSwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDEpLCB2anVzdCA9IDEuNSwgY29sb3IgPSAiYmxhY2siLCBzaXplID0gMykgKwogIHNjYWxlX2ZpbGxfbWFudWFsKG5hbWUgPSAiU2l0dWHDp8OjbyIsIHZhbHVlcyA9IGMoIiNkMzI5MGYiLCAiIzUyZDA1MyIpLCBsYWJlbHMgPSBjKCJWYXNjbyIsICJWaXZldSIpKSArCiAgc2NhbGVfeF9kaXNjcmV0ZShsaW1pdHM9YygiMSIsICIyIiwgIjMiKSkgKwogIGxhYnModGl0bGUgPSAiUXVhbnRpZGFkZSBkZSBzb2JyZXZpdmVudGVzIGUgw7NiaXRvcyBwb3IgY2xhc3NlIGRlIHBhc3NhZ2Vpcm9zIiwgeCA9ICJDbGFzc2UiLCB5ID0gIlByb3BvcsOnw6NvIikKCmBgYAoKIyMjIyMgQW7DoWxpc2UgbmFzIE1lc21hcyBQcm9wb3LDp8O1ZXMKPiBOw7ptZXJvIGJydXRvIGRlIHNvYnJldml2ZW50ZXMgZSBuw6NvIHNvYnJldml2ZW50ZXMgcG9yIGNsYXNzZSBlIHNleG8uCgotICBOb3ZhbWVudGUsIHBlcmNlYmUtc2UgYSBtYWlvciBwb3JjZW50YWdlbSBkZSBzb2JyZXZpdsOqbmNpYSBlbnRyZSBtdWxoZXJlcywgcHJpbmNpcGFsbWVudGUgZGUgY2xhc3NlcyBtYWlzIGFsdGFzLgoKLSAgSW50ZXJlc3NhbnRlIG8gZmF0byBkZSBxdWUgbyBuw7ptZXJvIGRlIG11bGhlcmVzIHF1ZSBzb2JyZXZpdmVyYW0gZSBuw6NvIHNvYnJldml2ZXJhbSBuYSB0ZXJjZWlyYSBjbGFzc2Ugw6kgZXhhdGFtZW50ZSBvIG1lc21vLCBzZWd1bmRvIGEgYmFzZSBhbmFsaXNhZGEuCgpgYGB7ciwgZmlnLndpZHRoPTksIGZpZy5oZWlnaHQ9NX0KZGYgJT4lCiAgbXV0YXRlKFN1cnZpdmVkID0gaWZlbHNlKFN1cnZpdmVkID09IDEsICJTdXJ2aXZlZCIsICJEaWVkIikpICU+JQogIGdyb3VwX2J5KFBjbGFzcywgU2V4LCBTdXJ2aXZlZCkgJT4lCiAgc3VtbWFyaXNlKGNvdW50ID0gbigpKSAlPiUKICBtdXRhdGUoUGVyY2VudGFnZSA9IHJvdW5kKGNvdW50L3N1bShjb3VudCkqMTAwLDIpKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBmYWN0b3IoUGNsYXNzKSwgeSA9IFBlcmNlbnRhZ2UsIGZpbGwgPSBTdXJ2aXZlZCkpICsKICBnZW9tX2NvbChwb3NpdGlvbiA9ICJkb2RnZSIpICsKICBnZW9tX3RleHQoYWVzKGxhYmVsID0gY291bnQpLCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMSksIHZqdXN0ID0gLTAuNSwgY29sb3IgPSAiIzIwMjEyNCIsIHNpemUgPSAzKSArCiAgc2NhbGVfZmlsbF9tYW51YWwobmFtZSA9ICJTb2JyZXZpdmV1PyIsIHZhbHVlcyA9IGMoIiNkMzI5MGYiLCAiIzUyZDA1MyIpLCBsYWJlbHMgPSBjKCJOw6NvIiwgIlNpbSIpKSArCiAgc2NhbGVfeF9kaXNjcmV0ZShsaW1pdHMgPSBjKCIxIiwgIjIiLCAiMyIpKSArCiAgZmFjZXRfd3JhcCh+U2V4LCBucm93ID0gMSwgc2NhbGVzID0gImZyZWVfeCIpICsKICBsYWJzKHRpdGxlID0gIkNvbXBhcmHDp8OjbyBkZSBzb2JyZXZpdmVudGVzIGUgw7NiaXRvcyBwb3IgY2xhc3NlIiwKICAgICAgIHN1YnRpdGxlID0gIkRhZG9zIHNlcGFyYWRvcyBwb3Igc2V4byIsCiAgICAgICB4ID0gIkNsYXNzZSIsCiAgICAgICB5ID0gIlBvcmNlbnRhZ2VtICglKSIsCiAgICAgICBmaWxsID0gIiIpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwKICAgICAgICBwYW5lbC5ncmlkLm1ham9yLnggPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vci54ID0gZWxlbWVudF9ibGFuaygpKQpgYGAKCiMjIyMjIFZpenVhbGl6YcOnw6NvIGVtIENvbXBhcmHDp8OjbyBhIFBvcHVsYcOnw6NvCj4gUmVsYcOnw6NvIGRvIG7Dum1lcm8gZGUgbW9ydGVzIHBlbG8gbsO6bWVybyB0b3RhbCBkZSBwYXNzYWdlaXJvcyBwb3Igc2V4by4KCi0gVmVtb3MgY29tbyBvIG7Dum1lcm8gcmVsYXRpdm8gZGUgbW9ydG9zIGRhIHRlcmNlaXJhIGNsYXNzZSDDqSBtdWl0byBtYWlvciBxdWUgY29tcGFyYWRvIGEgb3V0cmFzIGNsYXNzZXMgZW0gYW1ib3Mgb3Mgc2V4b3MuCgotICBNZXNtbyBhc3NpbSwgbyBuw7ptZXJvIHJlbGF0aXZvIGRlIHNvYnJldml2ZW50ZXMgaG9tZW5zIG5hIHRlcmNlaXJhIGNsYXNzZSDDqSBtYWlvciBxdWUgZGEgc2VndW5kYSBjbGFzc2UuIAoKYGBge3IsIGZpZy53aWR0aD05LCBmaWcuaGVpZ2h0PTV9CiMgQWdydXBhIG9zIGRhZG9zIHBvciBjbGFzc2UgZGUgcGFzc2FnZWlyb3MsIGfDqm5lcm8gZSBzb2JyZXZpdsOqbmNpYQpzdXJ2aXZhbF9ieV9jbGFzc19nZW5kZXIgPC0gZGYgJT4lCiAgZ3JvdXBfYnkoUGNsYXNzLCBTdXJ2aXZlZCwgU2V4KSAlPiUKICBzdW1tYXJpc2UoY291bnQgPSBuKCkpCgojIENhbGN1bGEgYSBwcm9wb3LDp8OjbyBlIG8gcGVyY2VudHVhbCBkZSBzb2JyZXZpdmVudGVzIGVtIGNhZGEgY2F0ZWdvcmlhCnN1cnZpdmFsX2J5X2NsYXNzX2dlbmRlciRwcm9wIDwtIHN1cnZpdmFsX2J5X2NsYXNzX2dlbmRlciRjb3VudCAvIHN1bShzdXJ2aXZhbF9ieV9jbGFzc19nZW5kZXIkY291bnQpCnN1cnZpdmFsX2J5X2NsYXNzX2dlbmRlciRwZXJjZW50IDwtIHBhc3RlMChyb3VuZChzdXJ2aXZhbF9ieV9jbGFzc19nZW5kZXIkcHJvcCAqIDEwMCwgMSksICIlIikKCiMgQ3JpYSB1bSBncsOhZmljbyBkZSBiYXJyYXMgZW1waWxoYWRhcyBjb20gYXMgcHJvcG9yw6fDtWVzIGRlIHNvYnJldml2w6puY2lhIHBvciBjbGFzc2UgZSBzb2JyZXZpdsOqbmNpYSwgCiMgY29sb3JpZG8gZGUgYWNvcmRvIGNvbSBhIHZhcmnDoXZlbCBkZSBzb2JyZXZpdsOqbmNpYQpnZ3Bsb3Qoc3Vydml2YWxfYnlfY2xhc3NfZ2VuZGVyLCBhZXMoeCA9IGZhY3RvcihQY2xhc3MpLCB5ID0gcHJvcCwgZmlsbCA9IGZhY3RvcihTdXJ2aXZlZCkpKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gInN0YWNrIikgKyAjIGluZGljYSBxdWUgw6kgdW0gZ3LDoWZpY28gZGUgYmFycmFzIGVtcGlsaGFkYXMKICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcGVyY2VudCksIHBvc2l0aW9uID0gcG9zaXRpb25fc3RhY2sodmp1c3QgPSAwLjUpKSArIAogIGxhYnModGl0bGUgPSAiUHJvcG9yw6fDo28gZGUgc29icmV2aXbDqm5jaWEgYW8gVG90YWwiLCB4ID0gIkNsYXNzZSIsIHkgPSAiUHJvcG9yw6fDo28iKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKSArCiAgc2NhbGVfZmlsbF9tYW51YWwobmFtZSA9ICJTb2JyZXZpdmV1PyIsIHZhbHVlcyA9IGMoIiNkMzI5MGYiLCAiIzUyZDA1MyIpLCBsYWJlbHMgPSBjKCJOw6NvIiwgIlNpbSIpKSArIAogIGZhY2V0X3dyYXAoLiB+IFNleCkgIyBhZGljaW9uYSB1bSBmYWNldF93cmFwIHBhcmEgc2VwYXJhciBvcyBncsOhZmljb3MgcG9yIGfDqm5lcm8KCmBgYAojIyMgVGl0YW5pYyBBbmFseXRjaXMKW0BnYWJyaWVsbHVpem9uZV0oaHR0cHM6Ly93d3cubGlua2VkaW4uY29tL2luL2dhYnJpZWxsdWl6b25lLykK